﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<vector>
using namespace std;

//309. 买卖股票的最佳时机含冷冻期
//https ://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/
//给定一个整数数组prices，其中第  prices[i] 表示第 i 天的股票价格 。​
//设计一个算法计算出最大利润。在满足以下约束条件下，你可以尽可能地完成更多的交易（多次买卖一支股票） :
//卖出股票后，你无法在第二天买入股票(即冷冻期为 1 天)。
//注意：你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。




//方法：动态规划
//dp[i]表示第i天结束后所得到的最大利润
// 
//根据题目信息，dp[i]可以划分为三个子状态如下
//dp[0][i]表示第i天结束后，出于买入状态的最大利润
//dp[1][i]表示第i天结束后，出于可交易状态的最大利润
//dp[2][i]表示第i天结束后，出于冷冻期状态的最大利润
// 
//画出状态机之后很容易得到以下状态转移方程：
//dp[0][i] = max(dp[1][i - 1] - prices[i], dp[0][i - 1]);
//dp[1][i] = max(dp[2][i - 1], dp[1][i - 1]);
//dp[2][i] = dp[0][i - 1] + prices[i];

//最后答案即为dp[0][n-1]，dp[1][n-1]，dp[2][n-1]三者取最值即可
class Solution {
public:
    int maxProfit(vector<int>& prices)
    {
        //1、创建dp表
        int n = prices.size();
        vector<vector<int>> dp(3, vector<int>(n));  //0：买入 1：可交易 2：冷冻期
        //2、初始化dp表
        dp[0][0] = -prices[0];
        dp[1][0] = 0;
        dp[2][0] = 0;
        //3、填表
        for (int i = 1; i < n; i++)
        {
            dp[0][i] = max(dp[1][i - 1] - prices[i], dp[0][i - 1]);
            dp[1][i] = max(dp[2][i - 1], dp[1][i - 1]);
            dp[2][i] = dp[0][i - 1] + prices[i];
        }
        return max(max(dp[0][n - 1], dp[1][n - 1]), dp[2][n - 1]);

    }
};